home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MACSHELL / MS1 / SHELL_SO / PARSE.C < prev    next >
Text File  |  1992-12-02  |  8KB  |  408 lines

  1. /*
  2.  *    MacShell Source File
  3.  *
  4.  *    Copyright (c) 1989, 1990, 1991, 1992  Suick Bay Technologies.  All rights reserved.
  5.  *
  6.  *
  7.  *    RESTRICTIONS ON MacShell program and source code.
  8.  *
  9.  *    Ñ╩MacShell¬ is a product of Suick Bay Technologies and is provided for
  10.  *    restricted use by the owner of the CDROM "Disk to the future II".
  11.  *
  12.  *    Ñ╩No permission is granted for any commercial use without the written
  13.  *    consent of the Suick Bay Technologies.
  14.  *
  15.  *    Ñ╩No permission is granted for any redistribution of any kind use without
  16.  *    the written consent of the Suick Bay Technologies.
  17.  *
  18.  *    Ñ╩Permission is granted to use this for any personal noncommercial use.
  19.  *
  20.  *    Ñ╩You may not distribute source or executable code at all, nor may you 
  21.  *    distribute it with or within a commercial product without the written
  22.  *    consent of the Suick Bay Technologies.  Please send modifications to 
  23.  *    the author for inclusion in updates to the program.  Thanks.
  24.  *
  25.  *
  26.  *    MacShell¬ IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  27.  *    WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  28.  *    PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  29.  *
  30.  *    SUICK BAY TECHNOLOGIES SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  31.  *    INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY MACSHELL
  32.  *    OR ANY PART THEREOF. 
  33.  *
  34.  *    In no event will Suick Bay Technologies be liable for any lost revenue
  35.  *    or profits or other special, indirect and consequential damages, even if
  36.  *    Suick Bay Technologies has been advised of the possibility of such damages.
  37.  *
  38.  *    Suick Bay Technologies can be reached at:
  39.  *    
  40.  *    8768 Cottonwood lane
  41.  *    Maple Grove, MN 55369
  42.  *    Voice: (612) 425-7025
  43.  *    AppleLink: D5233
  44.  *    
  45.  *
  46.  *    No parts of this software may be reproduced or stored in a
  47.  *    retrieval system or transmitted in any form, or any means,
  48.  *    electronic, mechanical, photocopying, recording or otherwise,
  49.  *    without the prior written permission of Suick Bay Technologies.
  50.  *    
  51.  *    Spread the word and not the disk.
  52.  *    
  53.  *    SPK 012290    :    Initial
  54.  */
  55.  
  56. #include    "System.h"
  57. #include    "Parse.h"
  58. #include    "Shell.h"
  59.  
  60. #define        SCRIPT
  61.  
  62. /*******************************************************************/
  63. /*
  64.  *    Special Characters
  65.  */
  66. Boolean        isPrint( char c )
  67. {
  68.     return( isprint(c)  );
  69. }
  70.  
  71. Boolean        isDigit( char c )
  72. {
  73.     return( c >= '0' && c <= '9' );
  74. }
  75.  
  76. Boolean        isSpecial( char    c )
  77. {
  78.     switch( c )
  79.         {
  80.         case    '|'        :
  81.         case    '&'        :
  82.         case    '$'        :
  83.         case    '<'        :
  84.         case    '>'        :
  85.         case    ';'        :
  86.         case    '('        :
  87.         case    ')'        :
  88.         case    '{'        :
  89.         case    '}'        :
  90.         case    '#'        :
  91.         case    '\''    :
  92.         case    '\"'    :
  93.             return( TRUE );
  94.             
  95.         default :
  96.             return( FALSE );
  97.         }
  98. }
  99.  
  100. char    spaces[ 32 ];
  101.  
  102. void    getSpaces()
  103. {
  104. char    *cp = ShellGetVar( currShell, "IFS" );
  105.  
  106.     strcpy( spaces, cp );
  107. }
  108.  
  109. Boolean    isShellSpace( char c )
  110. {
  111. char    *cp = spaces;
  112.  
  113.     while( *cp )
  114.         {
  115.         if( *cp == c )
  116.             return( TRUE );
  117.         cp++;
  118.         }
  119.         
  120.     return( FALSE );
  121. }
  122.  
  123. /*******************************************************************/
  124. /*
  125.  *    Token separator
  126.  */
  127. char    *GetShellToken( char *str, char *buf, int *type )
  128. {
  129. char    *bufBase;
  130.  
  131.     getSpaces();
  132.     bufBase = buf;
  133.     *buf = '\0';
  134.     *type = tkn_unknown;
  135.     
  136.     if( str == NULL || *str == '\0' )
  137.         {
  138.         *type = tkn_eol;
  139.         return( NULL );
  140.         }
  141.     
  142.     while( isShellSpace( *str ) )    /* remove white space */
  143.         str++;
  144.  
  145.     switch( *str )
  146.         {
  147.         case    '\r'    :
  148.         case    '\n'    :
  149.         case    '\0'    :
  150.             *type = tkn_eol;
  151.             
  152.             if( *str == '\0' )
  153.                 return( NULL );
  154.                 
  155.             break;
  156.  
  157.         case    '|'        :
  158.             *buf++ = *str++;
  159.             switch( *str )
  160.                 {
  161.                 case    '|'    :
  162.                     *type = tkn_orf;
  163.                     *buf++ = *str++;
  164.                     break;
  165.                     
  166.                 case    '&'    :
  167.                     *type = tkn_pipeOutErr;
  168.                     *buf++ = *str++;
  169.                     break;
  170.                     
  171.                 default :
  172.                     *type = tkn_pipe;
  173.                     break;
  174.                 }                
  175.             break;
  176.             
  177.         case    '&'        :
  178.             *buf++ = *str++;
  179.             switch( *str )
  180.                 {
  181.                 case    '&'    :
  182.                     *type = tkn_andf;
  183.                     *buf++ = *str++;
  184.                     break;
  185.                     
  186.                 default :
  187.                     *type = tkn_background;
  188.                     break;
  189.                 }                
  190.             break;
  191.             
  192.         case    '$'        :
  193.             *buf++ = *str++;
  194.             *type = tkn_var;
  195.             break;
  196.             
  197.         case    '<'        :
  198.             *buf++ = *str++;
  199.             switch( *str )
  200.                 {
  201.                 case    '<'    :
  202.                     *type = tkn_inputFromHere;
  203.                     *buf++ = *str++;
  204.                     break;
  205.                     
  206.                 default :
  207.                     *type = tkn_inputRedirect;
  208.                     break;
  209.                 }                
  210.             break;
  211.  
  212.         case    '>'        :
  213.             *buf++ = *str++;
  214.             switch( *str )
  215.                 {
  216.                 case    '>'    :
  217.                     *type = tkn_outputAppend;
  218.                     *buf++ = *str++;
  219.                     break;
  220.                     
  221.                 default :
  222.                     *type = tkn_outputRedirect;
  223.                     break;
  224.                 }                
  225.             break;
  226.  
  227.         case    ';'        :
  228.             *buf++ = *str++;
  229.             switch( *str )
  230.                 {
  231.                 case    ';'    :
  232.                     *type = tkn_caseDelimit;
  233.                     *buf++ = *str++;
  234.                     break;
  235.                     
  236.                 default :
  237.                     *type = tkn_separator;
  238.                     break;
  239.                 }                
  240.             break;
  241. #ifdef    SCRIPT
  242.         case    '('        :
  243.             *buf++ = *str++;
  244.             *type = tkn_leftParen;
  245.             break;
  246.                             
  247.         case    ')'        :
  248.             *buf++ = *str++;
  249.             *type = tkn_rightParen;
  250.             break;
  251.                             
  252.         case    '{'        :
  253.             *buf++ = *str++;
  254.             *type = tkn_leftCurl;
  255.             break;
  256.                             
  257.         case    '}'        :
  258.             *buf++ = *str++;
  259.             *type = tkn_rightCurl;
  260.             break;
  261.                             
  262.         case    '#'        :
  263.             *buf++ = *str++;
  264.             *type = tkn_comment;
  265.             break;
  266. #endif            
  267.         case    '\''    :
  268.             str++;        /* Move Past Quote */
  269.             while ( *str && *str != '\'' )
  270.                 {
  271.                 *buf++ = *str++;
  272.                 }
  273.             
  274.             if( *str == '\0' )        /* did not find matching quote */
  275.                 {
  276.                 
  277.                 }
  278.                 
  279.             *buf = '\0';
  280.             str++;        /* Move Past Quote */
  281.             
  282.             *type = tkn_identifier;
  283.             break;
  284.             
  285.         case    '\"'    :
  286.             *buf++ = *str++;
  287.             *type = tkn_doubleQuote;
  288.             break;
  289.             
  290.         default    :
  291.             {
  292.             Boolean        isNumber = TRUE;
  293.             
  294.             while ( *str && !isShellSpace(*str) && !isSpecial(*str) )
  295.                 {
  296.                 if( !isDigit( *str ))
  297.                     isNumber = FALSE;
  298.                     
  299.                 *buf++ = *str++;
  300.                 }
  301.             *buf = '\0';
  302. #ifdef    SCRIPT            
  303.             if( strcmp( bufBase, "if" ) == 0 )
  304.                 *type = tkn_if;
  305.             else if( strcmp( bufBase, "then" ) == 0 )
  306.                 *type = tkn_then;
  307.             else if( strcmp( bufBase, "else" ) == 0 )
  308.                 *type = tkn_else;
  309.             else if( strcmp( bufBase, "elif" ) == 0 )
  310.                 *type = tkn_elif;
  311.             else if( strcmp( bufBase, "fi" ) == 0 )
  312.                 *type = tkn_fi;
  313.                 
  314.             else if( strcmp( bufBase, "case" ) == 0 )
  315.                 *type = tkn_case;
  316.             else if( strcmp( bufBase, "in" ) == 0 )
  317.                 *type = tkn_in;
  318.             else if( strcmp( bufBase, "esac" ) == 0 )
  319.                 *type = tkn_esac;
  320.                 
  321.             else if( strcmp( bufBase, "for" ) == 0 )
  322.                 *type = tkn_for;
  323.             else if( strcmp( bufBase, "while" ) == 0 )
  324.                 *type = tkn_while;
  325.             else if( strcmp( bufBase, "until" ) == 0 )
  326.                 *type = tkn_until;
  327.             else if( strcmp( bufBase, "do" ) == 0 )
  328.                 *type = tkn_do;
  329.             else if( strcmp( bufBase, "done" ) == 0 )
  330.                 *type = tkn_done;
  331.                 
  332.             else if( strcmp( bufBase, "break" ) == 0 )
  333.                 *type = tkn_break;
  334.             else if( strcmp( bufBase, "continue" ) == 0 )
  335.                 *type = tkn_continue;
  336.             else if( strcmp( bufBase, "exit" ) == 0 )
  337.                 *type = tkn_exit;
  338.             else
  339.                 
  340. #endif
  341.                 if( isNumber )
  342.                 *type = tkn_digit;
  343.             else
  344.                 *type = tkn_identifier;
  345.             }
  346.             break;
  347.         }
  348.         
  349.     *buf++ = '\0';
  350.     
  351.     return( str );
  352. }
  353.  
  354. /*******************************************************************/
  355.  
  356. void        ExpandShellStr( WHandle ShellWh, char *string )
  357. {
  358. char        *sp, *bp, *vp, *bep, buf[ 256 ], varBuf[ 64 ];
  359. Boolean        expanded = FALSE;
  360.  
  361.     sp = string;
  362.     bp = buf;
  363.     bep = buf + 256;
  364.     
  365.     while( *sp && (bp<bep))
  366.         {
  367.         if( *sp == '\'' )        /* Quote, pass all chars to next quote */            
  368.             {
  369.             *bp++ = *sp++;        /* save the quote */
  370.             while( *sp && (*sp != '\''))
  371.                 *bp++ = *sp++;
  372.             *bp++ = *sp++;        /* save the quote */
  373.             }
  374.         else if( *sp == '$' )    /* start of a shell var */
  375.             {
  376.             vp = varBuf;
  377.             sp++;
  378.             
  379.             while( *sp && !isShellSpace(*sp) && !isSpecial(*sp) )
  380.                 *vp++ = *sp++;
  381.  
  382.             vp = ShellGetVar( ShellWh, varBuf );
  383.             
  384.             if( *vp )    /* will always return a string, may not have any data */
  385.                 {
  386.                 while( *vp )        /* copy var to buf string */
  387.                     *bp++ = *vp++;
  388.                     
  389.                 expanded = TRUE;
  390.                 }
  391.             else
  392.                 {
  393.                 *bp++ = '$';        /* re-enter the $ */
  394.                 vp = varBuf;
  395.                 while( *vp )        /* no var, copy back to buf string */
  396.                     *bp++ = *vp++;
  397.                 }
  398.             }
  399.         else
  400.             *bp++ = *sp++;
  401.         }
  402.         
  403.     *bp = '\0';
  404.         
  405.     if( expanded )
  406.         strcpy( string, buf );    /* copy the expanded string back */
  407. }
  408.